#ifndef CSERVICEBACKEND_H
#define CSERVICEBACKEND_H

#include <QObject>
#include "libxl.h"
#include <QVariantMap>
#include <QVector>
#include <QFont>
#include <QMarginsF>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QStandardPaths>
#include <QPdfWriter>
#include <QPainter>
#include <QtMath>
#include <QMutex>

using namespace libxl;

struct SetMessge
{//保存出题信息，包括题型名称、数量及分值
    QString m_TestName;//题型名称
    int m_testNum;//题型数量
    double m_fenZhi;//题型分值
};
struct PageSetting
{//保存页面设置信息
    QString pageSize ;//页面纸张规格大小
    QMarginsF pageMarMargins;//页边距
    bool isDoublePage;//是否双面打印
    bool islandScape;//是否为横向页面
    bool isZhuangDing;//考生信息是否装订在侧面
    QFont h1Font;//主标题字体
    QFont h2Font;//一级标题字体
    QFont hcFont;//正文字体
    QFont ksFont;//考生信息字体
    int hJianju;//行间距，单位Pt
    int ppi;//分辨率
};

class CServiceBackend : public QObject
{
    Q_OBJECT
public:
    explicit CServiceBackend(QObject *parent = nullptr);
    ~ CServiceBackend();
    //处理错误消息
    Q_INVOKABLE QString getError();//返回错误信息
    void setError(QString error);//设置错误消息
    //读取Excel文件
    Q_INVOKABLE void setExcelFileName(QString name);//获取文件名
    bool openExcelFile();//打开Excel文件
    Q_INVOKABLE bool readItemBankMsg();//读取题库信息
    Q_INVOKABLE QVariantMap getItemBankMsg();//用户获取题库信息
    //获取组卷设置
    Q_INVOKABLE void appendTestPaperSet(QString testName,int testNum,double fenZhi);//将试题信息发送给m_testPaperSet，用于打印试卷
    Q_INVOKABLE void clearTestPaperSet();//清除试卷设置数组m_testPaperSet
    //获取页面设置
    Q_INVOKABLE void readPageSetting(QVariantMap map);//获取页面设置信息,写入m_mainPageSetting
    //获取试卷标题
    Q_INVOKABLE bool getTestPaperTittle(QString tittle);//试卷标题
    //按照设置打印PDF试卷
    Q_INVOKABLE bool printTestPaper();
    //试卷生成辅助函数：写入文本hJianju行间距，text需要写入的内容，isCenter文本是否居中,首行缩进的字符数indentNum,topMargin设置第一行的上间距，特殊下可能与内部行间距不同，比如标题上面不需要行间距
    void writeText(QString text,QFont font,qreal hJianju,qreal topMargin,bool isCenter,int indentNum);
    void xiPaiVector(QVector<int> *vector);//洗牌算法
    bool writeQuestionOrAnswer(bool isQuestion,qreal hJianju);//写入试题

signals:
    void error();//出现错误以后发出信号
    void readReady();//通知用户，读取题库信息成功的信号
private:
    QString m_error;//保存错误信息
    Book *m_book;//Excel文件
    Sheet *m_sheet;//工作表
    QString m_excelFileName;//题库文件路径
    //保存题库各题型信息
    QVariantMap m_itemBankMsg;//以键值对的形式保存各题型及数量，QMap<QString, QVariant>
    //存储所有题型所在的行号，方便后续抽题和读题
    QVector<int> m_dTiXingList;//单选题行号列表
    QVector<int> m_dxTiXingList;//多选题行号列表
    QVector<int> m_pTiXingList;//判断题行号列表
    QVector<int> m_tTiXingList;//填空题行号列表
    QVector<int> m_jTiXingList;//简答题行号列表
    //保存组题信息
    QList <SetMessge> m_testPaperSet;//保存试卷出题的题型及各题型的出题数量
    //保存页面设置信息
    PageSetting m_mainPageSetting;//全部页面设置信息
    //试卷标题
    QString m_testPaperTittle;
    //创建一个PDF设备对象
    QPdfWriter *m_pdfWriter;
    //创建绘图对象
    QPainter *m_pPainter;
    //绘制起点
    qreal m_xStart;
    qreal m_yStart;
    //是否奇数页
    bool m_isOddPage;
    QMutex mutex;
};

#endif // CSERVICEBACKEND_H
